package com.nnnu.wsnackshop.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * RabbitMQ配置类
 * 只有当spring.rabbitmq.enabled为true时才启用
 */
@Configuration
@ConditionalOnProperty(name = "spring.rabbitmq.enabled", havingValue = "true", matchIfMissing = false)
public class RabbitMQConfig {

    /**
     * 库存交换机
     */
    public static final String INVENTORY_EXCHANGE = "inventory.exchange";

    /**
     * 库存减少队列
     */
    public static final String INVENTORY_DECREASE_QUEUE = "inventory.decrease.queue";

    /**
     * 库存增加队列
     */
    public static final String INVENTORY_INCREASE_QUEUE = "inventory.increase.queue";

    /**
     * 库存减少路由键
     */
    public static final String INVENTORY_DECREASE_ROUTING_KEY = "inventory.decrease";

    /**
     * 库存增加路由键
     */
    public static final String INVENTORY_INCREASE_ROUTING_KEY = "inventory.increase";

    /**
     * 定义JSON消息转换器
     */
    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    /**
     * 配置RabbitTemplate，设置消息转换器和回调
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(jsonMessageConverter());

        // 消息是否到达交换机的回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack) {
                System.out.println("消息未到达交换机: " + cause);
            }
        });

        // 消息是否从交换机到达队列的回调
        rabbitTemplate.setReturnsCallback(returned -> {
            System.out.println("消息从交换机路由到队列失败: " + returned.getMessage());
        });

        return rabbitTemplate;
    }

    /**
     * 声明库存交换机
     */
    @Bean
    public DirectExchange inventoryExchange() {
        return new DirectExchange(INVENTORY_EXCHANGE, true, false);
    }

    /**
     * 声明库存减少队列
     */
    @Bean
    public Queue inventoryDecreaseQueue() {
        return QueueBuilder.durable(INVENTORY_DECREASE_QUEUE).build();
    }

    /**
     * 声明库存增加队列
     */
    @Bean
    public Queue inventoryIncreaseQueue() {
        return QueueBuilder.durable(INVENTORY_INCREASE_QUEUE).build();
    }

    /**
     * 将库存减少队列绑定到交换机
     */
    @Bean
    public Binding inventoryDecreaseBinding() {
        return BindingBuilder.bind(inventoryDecreaseQueue())
                .to(inventoryExchange())
                .with(INVENTORY_DECREASE_ROUTING_KEY);
    }

    /**
     * 将库存增加队列绑定到交换机
     */
    @Bean
    public Binding inventoryIncreaseBinding() {
        return BindingBuilder.bind(inventoryIncreaseQueue())
                .to(inventoryExchange())
                .with(INVENTORY_INCREASE_ROUTING_KEY);
    }
}